package config

import (
	"bufio"
	"crypto/sha1"
	"fmt"
	"io"
	"log"
	"os"
	"path/filepath"
	"sort"
	"strconv"
	"strings"
	"time"
)

var (
	mapCFG            map[string]string // 配置选项
	KtvConfigFilePath string            // 配置文件的

	lastUpdateDate int64
)

// 初始化
func init() {
	mapCFG = make(map[string]string)
	KtvConfigFilePath = filepath.Join("SYSTEM", "KtvCenter.cfg")

	init_config()
}

// 初始化配置
func init_config() {

	// 默认的用户名为admin
	SetValue("goserver_username", "admin")

	// 默认用户密码为admin
	pass_sha1 := fmt.Sprintf("%x", sha1.Sum([]byte("admin")))
	SetValue("goserver_password", pass_sha1)

	mapCFG["ddns_name"] = ""
	mapCFG["ddns_key"] = ""
	mapCFG["ddns_enable"] = "0"

	// 今天的下载数量限制

	// 是否启用下载限制
	SetValue("download_limit_enable", "0")
	SetValue("download_limit_count", "30")
	SetValue("download_limit_speed", "200")

}

func LoadConfig() bool {

	ReloadConfig()

	return true
}

// 保存配置
func SaveConfig() bool {

	f, err := os.Create(KtvConfigFilePath)

	if err != nil {
		log.Printf("SaveConfig err = %v\n", err)
		return false
	}

	defer f.Close()

	err2 := write(f)

	if err2 != nil {
		return false
	} else {
		return true
	}

}

func ReloadConfig() {

	if time.Now().Unix() < lastUpdateDate+3 {
		return
	}

	reloadConfig()
}

func reloadConfig() bool {

	lastUpdateDate = time.Now().Unix()

	log.Printf("ReloadConfig, FilePath = %v\n", KtvConfigFilePath)

	f, err := os.Open(KtvConfigFilePath)

	if err != nil {
		log.Printf("LoadConfig err = %v\n", err)
		return false
	}

	defer f.Close()

	err2 := read(f)
	if err2 != nil {
		return false
	} else {
		return true
	}

}

// 获取新的值
func GetValue(key string, defaultVal string) string {

	key = strings.ToLower(key)
	if val, ok := mapCFG[key]; ok {
		return val
	}

	return defaultVal
}

// 获取数字变量
func GetIntValue(key string, defaultVal int) int {

	key = strings.ToLower(key)
	if val, ok := mapCFG[key]; ok {

		nValue, err := strconv.Atoi(val)
		if err == nil {
			return nValue
		}
	}

	return defaultVal
}

// 设置新的值
func SetValue(key string, val string) {
	key = strings.ToLower(key)
	mapCFG[key] = val
}

func read(reader io.Reader) (err error) {

	buf := bufio.NewReader(reader)

	for {
		line, err := buf.ReadString('\n')
		line = strings.TrimSpace(line)
		lineLengh := len(line) //[SWH|+]
		if err != nil {
			if err != io.EOF {
				return err
			}

			// Reached end of file, if nothing to read then break,
			// otherwise handle the last line.
			if lineLengh == 0 {
				break
			}
		}

		// empty line
		if lineLengh == 0 {
			continue
		}

		// Comment
		if line[0] == '#' || line[0] == ';' {
			continue
		}

		// find =
		pos := strings.Index(line, "=")
		if pos <= 0 {
			continue
		}

		key := strings.ToLower(strings.TrimSpace(line[0:pos]))
		val := strings.TrimSpace(line[pos+1:])
		mapCFG[key] = val

		//log.Printf("%s = %s", key, val)

	} // end for

	return nil

}

func write(w io.Writer) (err error) {

	sorted_keys := make([]string, 0)

	for key := range mapCFG {
		sorted_keys = append(sorted_keys, key)
	}

	// sort 'string' key in increasing order
	sort.Strings(sorted_keys)

	for _, key := range sorted_keys {
		val := mapCFG[key]
		line := fmt.Sprintf("%s = %s\r\n", key, val)
		io.WriteString(w, line)
	}

	return nil
}
